package tests;

import static org.junit.Assert.*;

import hexgame.GameLogic;
import hexgame.GameState;
import hexgame.HexMove;
import hexgame.HexPlayer;

import network.HexNetwork;

import org.junit.Before;
import org.junit.Test;

import search.Search;

public class HexGameLogicTests {

	GameState state;
	
	@Before
	public void setUp() throws Exception {
		
		state = new GameState(6, true);
	}

	@Test
	public void testWrongPlayerMove() {
		assertFalse(GameLogic.isValidMove(state, new HexMove(2, 2, HexPlayer.BLUE_REMOTE)));
		assertTrue(GameLogic.isValidMove(state, new HexMove(2, 2, HexPlayer.RED_LOCAL)));
	}
	
	@Test
	public void testWrongPlayerMove2() {
		assertFalse(GameLogic.isValidMove(state, new HexMove(2, 2, HexPlayer.BLUE_REMOTE)));
		assertFalse(GameLogic.isValidMove(state, new HexMove(2, 2, HexPlayer.BLUE_REMOTE)));
	}
	
	@Test
	public void testBasicValidMove() {
		assertTrue(GameLogic.isValidMove(state, new HexMove(2, 2, HexPlayer.RED_LOCAL)));
		
	}
	
	@Test
	public void testBasicSecondValidMove() {
		
		HexMove move = new HexMove(0, 2, HexPlayer.RED_LOCAL);
		assertTrue(GameLogic.isValidMove(state, move));
		
		GameLogic.makeMove(state, move);
		
		assertTrue(GameLogic.isValidMove(state, new HexMove(2, 0, HexPlayer.BLUE_REMOTE)));
	}
	
	@Test
	public void testOnBoard() {
		HexMove move = new HexMove(0, 0, HexPlayer.RED_LOCAL);
		assertTrue(GameLogic.isOnBoard(move, state));
		
		move = new HexMove(5, 5, HexPlayer.RED_LOCAL);
		assertTrue(GameLogic.isOnBoard(move, state));
		
		move = new HexMove(6, 5, HexPlayer.RED_LOCAL);
		assertFalse(GameLogic.isOnBoard(move, state));
		
		move = new HexMove(5, 6, HexPlayer.RED_LOCAL);
		assertFalse(GameLogic.isOnBoard(move, state));
		
		move = new HexMove(6, 6, HexPlayer.RED_LOCAL);
		assertFalse(GameLogic.isOnBoard(move, state));
		
		move = new HexMove(-1, -1, HexPlayer.RED_LOCAL);
		assertFalse(GameLogic.isOnBoard(move, state));
	}
	
	@Test
	public void testGetShortestPath() {
		HexMove[] moves = Search.leastTurnsToEdge(new HexMove(0,0, HexPlayer.NONE), state, true);
		
		for(HexMove move : moves) {
			System.out.println(HexNetwork.formatMove(move.getX(), move.getY()));
		}
		
		assertEquals(6, moves.length);
		
		HexMove move = new HexMove(moves[0].getX(), moves[0].getY(), HexPlayer.RED_LOCAL);
		
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		
		moves = Search.leastTurnsToEdge(new HexMove(0,0, HexPlayer.RED_LOCAL), state, true);
		assertEquals(5, moves.length);
		
	}
	
	@Test
	public void testCompleteGame() {
		HexMove move = new HexMove(0, 5, HexPlayer.RED_LOCAL);
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		assertEquals(HexPlayer.NONE, GameLogic.playerWon(state));
		
		move = new HexMove(5, 0, HexPlayer.BLUE_REMOTE);
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		assertEquals(HexPlayer.NONE, GameLogic.playerWon(state));
		
		move = new HexMove(1, 5, HexPlayer.RED_LOCAL);
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		assertEquals(HexPlayer.NONE, GameLogic.playerWon(state));
		
		move = new HexMove(5, 1, HexPlayer.BLUE_REMOTE);
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		assertEquals(HexPlayer.NONE, GameLogic.playerWon(state));
		
		move = new HexMove(2, 5, HexPlayer.RED_LOCAL);
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		assertEquals(HexPlayer.NONE, GameLogic.playerWon(state));
		
		move = new HexMove(5, 2, HexPlayer.BLUE_REMOTE);
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		assertEquals(HexPlayer.NONE, GameLogic.playerWon(state));
		
		move = new HexMove(3, 5, HexPlayer.RED_LOCAL);
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		assertEquals(HexPlayer.NONE, GameLogic.playerWon(state));
		
		move = new HexMove(5, 3, HexPlayer.BLUE_REMOTE);
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		assertEquals(HexPlayer.NONE, GameLogic.playerWon(state));
		move = new HexMove(4, 5, HexPlayer.RED_LOCAL);
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		assertEquals(HexPlayer.NONE, GameLogic.playerWon(state));
		
		move = new HexMove(5, 4, HexPlayer.BLUE_REMOTE);
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		assertEquals(HexPlayer.NONE, GameLogic.playerWon(state));

		move = new HexMove(5, 5, HexPlayer.RED_LOCAL);
		assertTrue(GameLogic.isValidMove(state, move));
		GameLogic.makeMove(state, move);
		
		assertEquals(HexPlayer.RED_LOCAL, GameLogic.playerWon(state));
	}
}
